﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Snowdreamist.Collection.Tree
{
    public abstract class TreeNodeCollectionBase<T> : ITreeNodeCollection<T> where T : ITreeNode<T>
    {
        public TreeNodeCollectionBase(T node, IList<T> internalList)
        {
            if (node == null)
                throw new ArgumentNullException("node");
            if (internalList == null)
                throw new ArgumentNullException("internalList");
            this._node = node;
            this._internalList = internalList;
        }

        public virtual int IndexOf(T item)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            return this._internalList.IndexOf(item);
        }

        public virtual void Insert(int index, T item)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            if (this.IsReadOnly)
                throw new InvalidOperationException("ReadOnly");
            item.Attach(this._node);
            try
            {
                this._internalList.Insert(index, item);
            }
            catch
            {
                item.Detach();
                throw;
            }
        }

        public virtual void RemoveAt(int index)
        {
            if (this.IsReadOnly)
                throw new InvalidOperationException("ReadOnly");
            var node = this._internalList[index];
            this.RemoveAt(index);
            node.Detach();
        }

        public virtual T this[int index]
        {
            get
            {
                return this._internalList[index];
            }
            set
            {
                if (this.IsReadOnly)
                    throw new InvalidOperationException("ReadOnly");
                this.Insert(index, value);
            }
        }

        public virtual void Add(T item)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            if (this.IsReadOnly)
                throw new InvalidOperationException("ReadOnly");
            item.Attach(this._node);
            try
            {
                this._internalList.Add(item);
            }
            catch
            {
                item.Detach();
                throw;
            }
        }

        public virtual void Clear()
        {
            if (this.IsReadOnly)
                throw new InvalidOperationException("ReadOnly");
            foreach (var item in this._internalList)
                item.Detach();
            this._internalList.Clear();
        }

        public virtual bool Contains(T item)
        {
            if (item == null)
                return false;
            return this._internalList.Contains(item);
        }

        public virtual void CopyTo(T[] array, int arrayIndex)
        {
            this._internalList.CopyTo(array, arrayIndex);
        }

        public virtual int Count
        {
            get
            {
                return this._internalList.Count;
            }
        }

        public virtual bool IsReadOnly { get; protected set; }

        public virtual bool Remove(T item)
        {
            if (this.IsReadOnly)
                throw new InvalidOperationException("ReadOnly");
            throw new NotImplementedException();
        }

        public virtual IEnumerator<T> GetEnumerator()
        {
            return this._internalList.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this._internalList.GetEnumerator();
        }

        #region private

        private IList<T> _internalList;

        private T _node;

        #endregion private
    }
}